package com.dullong.firedocmanager.lucene4;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.dullong.firedocmanager.bean.Document;
import com.dullong.firedocmanager.bean.PDocument;
import com.dullong.firedocmanager.bean.PageBean;
import com.dullong.firedocmanager.util.OptionUtil;

public abstract class LuceneBase {

	protected final static Log baselog = LogFactory.getLog(SearchHelper.class);
	protected final static int MAX_COUNT = 1000;
	private static String indexPath;
	private static Analyzer analyzer;
	private static Formatter highlighter_formatter;
	private static Directory dir;
	private static IndexWriter indexWriter;
	private static IndexSearcher indexSearcher;

	public static IndexSearcher getIndexSearcher() throws IOException {
		return indexSearcher == null ? indexSearcher = new IndexSearcher(DirectoryReader.open(getDir())) : indexSearcher;
	}

	public static Directory getDir() throws IOException {
		return dir == null ? dir = FSDirectory.open(new File(getIndexPath())) : dir;
	}

	public static IndexWriter getIndexWriter() throws IOException {
		return indexWriter == null ? openIndexWriter(false) : indexWriter;
	}

	private static IndexWriter openIndexWriter(boolean tag) throws IOException {
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, getAnalyzer());
		if (tag) {
			config.setOpenMode(OpenMode.CREATE);
		} else {
			config.setOpenMode(OpenMode.CREATE_OR_APPEND);
		}
		indexWriter = new IndexWriter(getDir(), config);
		return indexWriter;
	}

	public static String getIndexPath() {
		return indexPath == null ? indexPath = FilenameUtils.normalize(OptionUtil.getOption("idx_path")) : indexPath;
	}

	public final static List<String> nowords = new ArrayList<String>() {
		{
			try {
				addAll(IOUtils.readLines(SearchHelper.class.getResourceAsStream("/stopword.dic")));
			} catch (IOException e) {
				baselog.error("Unabled to read stopword file", e);
			}
		}
	};

	private final static List<String> ReserveKeys = new ArrayList<String>() {
		{
			try {
				addAll(IOUtils.readLines(SearchHelper.class.getResourceAsStream("/keywords.dic")));
			} catch (IOException e) {
				baselog.error("Unabled to read keywords file", e);
			}
		}
	};

	public static Analyzer getAnalyzer() {
		return analyzer == null ? analyzer = new IKAnalyzer() : analyzer;
	}

	public static Formatter getHighlighter_formatter() {
		return highlighter_formatter == null ? highlighter_formatter = new SimpleHTMLFormatter("<span class=\"highlight\">", "</span>") : highlighter_formatter;
	}

	protected PDocument LD2PD(List<org.apache.lucene.document.Document> document, Long count, Long page, Long limit, String keyword) {
		List<Long> docid = new ArrayList<Long>();
		for (org.apache.lucene.document.Document d : document) {
			docid.add(Long.valueOf(d.get("ID")));
		}

		Query query = SearchHelper.makeQuery("body", keyword, 1.0f);

		List<Document> documents = DocumentCreater.creatDoc(query, docid.toArray(new Long[docid.size()]));

		PageBean pageBean = new PageBean(page, limit, count);

		PDocument pDocument = new PDocument(documents, pageBean);

		return pDocument;
	}

	/**
	 * 获取编号为 docNum最相近的文档
	 * 
	 * @param docNum
	 * @param count
	 * @param fieldNames
	 * @param objClass
	 * @return
	 * @throws IOException
	 */
	public List<Searchable> moreLikeThis(int docNum, int count, String[] fieldNames) throws IOException {
		IndexSearcher searcher = getIndexSearcher();
		Query query = SearchHelper.makeQuery(searcher, docNum, fieldNames);
		TopDocs hits = searcher.search(query, count);
		System.out.println(query.toString());
		List<Searchable> results = new ArrayList<Searchable>();
		for (int i = 0; i < hits.totalHits&&i<count; i++) {
			System.out.println("-------------------"+docNum+":"+i+":"+hits.totalHits);
			ScoreDoc s_doc = (ScoreDoc) hits.scoreDocs[i];
			org.apache.lucene.document.Document doc = searcher.doc(s_doc.doc);
			Searchable obj = SearchHelper.doc2obj(doc);
			if (obj != null && !results.contains(obj)) {
				results.add(obj);
			}
		}
		return results;
	}
}
